package com.netty.gpt3;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class NettyClient {
    private final String host;
    private final int port;

    public NettyClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void run() {
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.group(new NioEventLoopGroup())   //指定EventLoopGroup
                    .channel(NioSocketChannel.class)   //指定通道类型
                    .remoteAddress(host, port)         //指定服务器地址和端口
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new ClientHandler());     //添加自定义ChannelHandler
                        }
                    });
            ChannelFuture future = bootstrap.connect().sync();    //连接到服务器
            System.out.println("连接成功！");

            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                String message = reader.readLine();     //从控制台输入消息
                if ("exit".equals(message)) {
                    future.channel().close().sync();
                    break;
                }
                future.channel().writeAndFlush(message + "\r\n");  //发送消息
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bootstrap.group().shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        NettyClient client = new NettyClient("localhost", 8888);   //指定服务器地址和端口
        client.run();
    }

    static class ClientHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            System.out.println("收到服务器消息：" + msg);
        }
    }
}

//        这个客户端程序实现了连接服务器、发送消息、接收消息的功能。首先创建了一个Bootstrap实例，使用NioEventLoopGroup作为EventLoopGroup，并指定通道类型为NioSocketChannel。在连接到服务器之前，添加了一个ChannelInitializer来进行初始化配置，同时向pipeline中添加自定义的ClientHandler处理器来接收服务器发来的消息。要发送消息，只要在控制台输入消息就行了，输出内容在ClientHandler处理器中打印。
